package GUI;

import java.awt.*;
import java.awt.geom.*;

// REMOVER
import java.awt.image.*;
import javax.imageio.*;

/**
 * Classe para manter as informações de objetos gráficos para desenho na tela.
 *
 * @author  (R. Soares)
 * @version (1.0 - 24-05-2010)
 */

public class ObjetoGUI
{
    // Variáveis de Instância --------------------------------------------------*
    private int _altura;
    private int _largura;
    private double coordenadaX;
    private double coordenadaY;
    private boolean visibilidade;
    private BufferedImage imagem;

    // Contrutores -------------------------------------------------------------- *
    /**
     * Cria um novo ObjetoGUI informando seu diametro, sua textura e sua
     * posição (coordenadas X e Y).
     *
     * @param int - diametro :  diametro do objeto
     * @param BufferedImage - imagem :textura do objeto
     * @param int - coordenadaX : coordenada X da posição do objeto
     * @param int - coordenadaY : coordenada Y da posição do objeto
     */
    public ObjetoGUI(int diametro, BufferedImage imagem,
                                               double coordenadaX, double coordenadaY)
    {
        _altura = diametro;
        _largura = diametro;
        this.imagem = imagem;

        /* As coordenadas do objeto posicionam o ponto superior esquerdo do retangulo
         * externo do objeto. Para posionar com relação ao centro deveser subtrair
         * metade do diametro de cada coordenada.
         */
        this.coordenadaX = coordenadaX - (diametro / 2);
        this.coordenadaY = coordenadaY - (diametro / 2);

        visibilidade = false;
    }

    /**
     * Cria um novo ObjetoGUI informando sua altura, sua largura, sua textura e sua
     * posição (coordenadas X e Y).
     *
     * @param int - altura :  altura do objeto
     * @param int - largura :  largura do objeto
     * @param BufferedImage - imagem :textura do objeto
     * @param int - coordenadaX : coordenada X da posição do objeto
     * @param int - coordenadaY : coordenada Y da posição do objeto
     */
    public ObjetoGUI(int altura, int largura, BufferedImage imagem,
                                               double coordenadaX, double coordenadaY)
    {
        _altura = altura;
        _largura = largura;
        this.imagem = imagem;

        /* As coordenadas do circulo posicionam o ponto superior esquerdo do retangulo
         * externo do circulo. Para posionar com relação ao centro deveser subtrair
         * metade do diametro de cada coordenada.
         */
        this.coordenadaX = coordenadaX - (largura / 2);
        this.coordenadaY = coordenadaY - (altura / 2);

        visibilidade = false;
    }

    /**
     * Torna o objeto visivel. Se ele já estiver visivel, não faz nada.
     */
    public void tornaVisivel()
    {
        visibilidade = true;
        draw(null, 0);
    }

    /**
     * Torna o objeto invisivel. Se ele já estiver invisivel, não faz nada.
     */
    public void tornaInvisivel()
    {
        erase();
        visibilidade = false;
    }

    /**
     * Apaga e Redesenha o objeto na posição informada, movendo de posição.
     * O movimento será linear.
     */
    public void move(double pX, double pY)
    {
        erase();
        coordenadaX =  pX - (_largura / 2);
        coordenadaY =  pY - (_altura / 2);
        draw(null, 0);
    }

    /**
     * Apaga e Redesenha o ojeto na posição informada, movendo de posição.
     * O movimento será circular.
     */
    public void moveCircular(double pX, double pY, double angulo)
    {
        erase();

        AffineTransform transform = new AffineTransform();
        transform.rotate(Math.toRadians(angulo) );

        AffineTransformOp transformOp = new AffineTransformOp(transform,
                                                                       AffineTransformOp.TYPE_BILINEAR);

        coordenadaX =  pX - (_largura / 2);
        coordenadaY =  pY - (_altura / 2);

        draw(transformOp, angulo);
    }


    /**
     * Desenha o objeto com as caracteristicas informadas.
     */
    private void draw(AffineTransformOp transformOp, double angulo)
    {
        if(visibilidade)
        {
           TelaJogo tela = TelaJogo.retornaTela();

           BufferedImage imagem = this.imagem;

           Rectangle2D.Double objetoImagem = new Rectangle2D.Double(
                                                                  coordenadaX, coordenadaY, _largura, _altura);
           TexturePaint imagePaint = null;
/*
           if(transform != null)
             objetoImagem =  transform.createTransformedShape( objetoImagem );
*/
           if(transformOp != null)
              imagem =  rotacionar (imagem, angulo);

             imagePaint = new TexturePaint(imagem, objetoImagem);

             tela.draw(this, objetoImagem, imagePaint);
        }
    }

    /**
     * Apaga o objeto da tela.
     */
    private void erase()
    {
        if(visibilidade) {
            TelaJogo tela = TelaJogo.retornaTela();
            tela.apagarImagem(this);
        }
    }



public BufferedImage rotacionar (BufferedImage original, double angulo)
{

    BufferedImage dest = new BufferedImage(
            original.getHeight(),
            original.getWidth(),
            original.getType());

    Graphics2D surface = dest.createGraphics();

    AffineTransform rotation = new AffineTransform();
    //Vamos desenhar a imagem em relação ao centro
    rotation.setToTranslation(
            (dest.getWidth() - original.getWidth()) / 2.0,
            (dest.getHeight() - original.getHeight()) / 2.0);

    //Também vamos rotacionar em relação ao centro
    rotation.rotate(
            Math.toRadians( angulo),
            original.getWidth()/2.0,
            original.getHeight()/2.0);

    //Definimos a matriz de transformação
    surface.transform(rotation);

    //Desenhamos a imagem
    surface.drawImage(original, 0, 0, null);
    surface.dispose();

    return dest;
}

}
